//
const isShowFlag = 'all'; //'all'

/**
 * 一、将下面异步代码使用Promise的方式改进
 */

function delay(x) {
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(x)
        },10)
    })
}

delay('hello').then(v=>{
    return delay(v+'lagou')
}).then(v=>{
    return delay(v+'I ❤️ U')
}).then(v=>{
    _log('一、执行结果',v)
})

/**
 * 二、基于以下代码完成下面的四个练习
 */

const fp = require('lodash/fp')

//数据
// horsepower 马力，dollar_value 价格，in_stock 库存
const cars = [
    {
        name:'Ferrari FF',
        horsepower: 660,
        dollar_value:700000,
        in_stock:true,
    },
    {
        name:'Spyker C12 Zagato',
        horsepower: 650,
        dollar_value:648000,
        in_stock:false,
    },
    {
        name:'Jaguar XKR-S',
        horsepower: 550,
        dollar_value:132000,
        in_stock:false,
    },
    {
        name:'Audi R8',
        horsepower: 525,
        dollar_value:114200,
        in_stock:false,
    },
    {
        name:'Aston Martin One-77',
        horsepower: 750,
        dollar_value:185000,
        in_stock:true,
    },
    {
        name:'Pagani Huayra',
        horsepower: 700,
        dollar_value:130000,
        in_stock:false,
    },
]

/**
 * 练习1：使用函数组合fp.flowRight()重新实现下面这个函数
 */
const isLastInStock = fp.flowRight(fp.prop('in_stock'),fp.last)

const result = isLastInStock(cars);
_log('二、1.执行结果',result);

/**
 * 练习2：使用fp.flowRight()、fp.prop()和fp.first() 获取第一个car的name
 */
const result2 = fp.flowRight(fp.prop('name'),fp.first)(cars)
_log('二、2.执行结果',result2);

/**
 * 练习3：使用帮助函数_average重构averageDollarValue，使用函数组合的方式实现
 */
let _average = function (xs) {
    return fp.reduce(fp.add,0,xs)/xs.length
} // <- 无须改动

let averageDollarValue = fp.flowRight(_average,fp.map(car=>car.dollar_value))

_log('二、3.执行结果',averageDollarValue(cars))

/**
 * 练习4：使用flowRight 写一个sanitizeNames()函数，返回一个下划线连接的小写字符串，
 * 把数组中的name转换为这种形式：例如 sanitizeNames(["Hello World"]) => ["hello_world"]
 */

let _underscore = fp.replace(/\W+/g,'_') // <-- 无须改动，并在sanitizeNames中使用它

const sanitizeNames = fp.map(fp.flowRight(fp.toLower,_underscore))

let result4 = sanitizeNames(['Hello World'])

_log('二、4.执行结果',result4)


/**
 * 三、基于下面提供的代码，完成后续的四个练习
 */

 /**
 * 练习1：使用fp.add(x,y)和fp.map(f,x)创建一个能让functor里的值增加的函数ex1
 */

const {Maybe, Container} = require('./support')

let maybe = Maybe.of([5,6,1])

let ex1 = (value) => {
    return maybe.map(fp.map(v=>fp.add(v,value)))
}

_log('三、1执行结果----',ex1(1))

/**
 * 练习2：实现一个函数ex2，能够使用fp.first 获取列表的第一个元素
 */

let xs = Container.of(['do','ray','me','fa','so','la','ti','do'])

let ex2 = () => {
    return xs.map(fp.first)._value;
}

_log('三、2执行结果',ex2())

/**
 * 练习3：实现一个函数ex3，使用safeProp 和 fp.first 找到user的名字的首字母
 */

 let safeProp = fp.curry(function(x,o){
    return Maybe.of(o[x])
 })

 let user = {id:2,name:'Albert'}
 
 let ex3 = (v) => {
    return safeProp('name')(v).map(fp.first)._value
 }

 _log('三、3执行结果',ex3(user))

 /**
  * 练习4：使用Maybe重写ex4，不要有if语句
  */
 let ex4 = function(n) {
     return Maybe.of(n).map(parseInt)._value;
 }

 _log('三、4执行结果1-',ex4(null))
 _log('三、4执行结果2-',ex4('123'))

 /**
  * 四、手写实现MyPromise源码
  */

  const MyPromise = require('./myPromise')

  const p = new MyPromise((resolve,reject)=>{
    resolve('成功')
  })

  p.then(v=>{
    _log('四、执行结果',v)
  },r=>{
    _log('四、执行结果',r)
  })


  // -----  调试log 用于屏蔽部分题的log
  function _log(flag,...message) {
      if (flag.includes(isShowFlag) || isShowFlag === 'all') {
        console.log(flag,...message)
      }
  }